﻿using LPP.Core.Helpers;
using Microsoft.AspNetCore.Http;
using Microsoft.IdentityModel.Tokens;
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;

namespace LPP.Core.Jwt
{
    public static class JwtHelper
    {
        private const string BearerPrefix = "Bearer ";

        /// <summary>
        /// 生成token令牌
        /// </summary>
        public static string CreateToken(Claim[] claimInfo, TokenManagement tokenManagement)
        {
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(tokenManagement.Secret));
            var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            var notTime = DateTime.UtcNow; // 使用 UTC 时间
            var expiresTime = notTime.AddMinutes(tokenManagement.AccessExpiration);

            var jwtToken = new JwtSecurityToken(
                tokenManagement.Issuer,
                tokenManagement.Audience,
                claims: claimInfo,
                notBefore: notTime,
                expires: expiresTime,
                signingCredentials: credentials);

            return new JwtSecurityTokenHandler().WriteToken(jwtToken);
        }

        /// <summary>
        /// 获取请求上下文Claims中的UserId
        /// </summary>
        public static string GetUserId(HttpContext httpContext) =>
            GetClaimValue(httpContext, ClaimTypes.Sid);

        /// <summary>
        /// 获取请求上下文Claims中的Name名称
        /// </summary>
        public static string GetName(HttpContext httpContext) =>
            GetClaimValue(httpContext, ClaimTypes.Name);

        private static string GetClaimValue(HttpContext httpContext, string claimType)
        {
            return httpContext.User?.Claims
                .FirstOrDefault(e => e.Type == claimType)?.Value ?? string.Empty;
        }

        /// <summary>
        /// 解析token获取JwtSecurityToken对象
        /// </summary>
        public static JwtSecurityToken GetSecurityToken(string token)
        {
            token = GetRemoveBearerToken(token);
            return new JwtSecurityTokenHandler().ReadJwtToken(token);
        }

        /// <summary>
        /// 获取token中存储的信息
        /// </summary>
        public static TokenPayload GetTokenPayload(HttpContext httpContext)
        {
            var token = GetRemoveBearerToken(httpContext.Request.Headers["Authorization"].ToString());
            return ExtractTokenPayload(token);
        }

        /// <summary>
        /// 获取token中存储的信息
        /// </summary>
        public static TokenPayload GetTokenPayload(string token)
        {
            token = GetRemoveBearerToken(token);
            return ExtractTokenPayload(token);
        }

        private static TokenPayload ExtractTokenPayload(string token)
        {
            var jwtToken = new JwtSecurityTokenHandler().ReadJwtToken(token);
            return new TokenPayload
            {
                Id = Convert.ToInt32(jwtToken.Payload[ClaimTypes.Sid]),
                Email = jwtToken.Payload[ClaimTypes.Email]?.ToString(),
                UserName = jwtToken.Payload[ClaimTypes.Surname]?.ToString(),
                Name = jwtToken.Payload[ClaimTypes.Name]?.ToString(),
                Role = jwtToken.Payload[ClaimTypes.Role]?.ToString()
            };
        }

        /// <summary>
        /// 获取去除字符串开头Bearer的token令牌
        /// </summary>
        public static string GetRemoveBearerToken(string token)
        {
            if (string.IsNullOrEmpty(token))
                throw new ArgumentNullException("传入的token为空!");

            return token.StartsWith(BearerPrefix) ? token.Replace(BearerPrefix, "") : token;
        }
    }
}
